/*
 * @Author: superRice
 * @Date: 2025-04-14 21:11:25
 * @LastEditors: superRice 1246333567@qq.com
 * @LastEditTime: 2025-04-27 23:39:35
 * @FilePath: /threejs-testing-dedicated/examples/stoneTablet/index.js
 * @Description:
 * Do your best to be yourself
 * Copyright (c) 2025 by superRice, All Rights Reserved.
 */
import * as TE from 'TEngine';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/Addons.js';
import { Pane } from 'tweakpane';

import CustomShaderMaterial from 'three-custom-shader-material/vanilla';

import vert from './shader/index.vert';
import frag from './shader/index.frag';

const TS = new TE.TEngine();
TS.camera.position.set(10, 10, 10);
TS.camera.lookAt(0, 0, 0);

const axes = new THREE.AxesHelper(5);
TS.scene.add(axes);

const directLight = new THREE.DirectionalLight(0xffffff, 10);
directLight.position.set(10, 10, 10);
TS.scene.add(directLight);

const light = new THREE.AmbientLight(0xffffff, 5); // 柔和的白光
TS.scene.add(light);

//开始计算模型的第二套uv
const computerUV2 = (mesh) => {
  const geometry = mesh.geometry;
  if (geometry.attributes.uv2) {
    console.error('已经存在第二套uv');
    return;
  }

  //开始计算
  const positionArray = geometry.attributes.position.array;

  //创建一个包围盒
  const box = new THREE.Box3();
  box.setFromArray(positionArray);

  //计算最大值到最小值的区间
  const size = box.getSize(new THREE.Vector3());
  console.log(size, 'size');

  const uv2Array = [];
  for (let i = 0; i < positionArray.length; i += 3) {
    const x = positionArray[i];
    const y = positionArray[i + 1];
    const z = positionArray[i + 2];
    const u = 1 - (box.max.x - x) / size.x;
    const v = 1 - (box.max.y - y) / size.y;
    // const v = 1 - (box.max.z - z) / size.z;

    uv2Array.push(u, v);
  }
  geometry.setAttribute('uv2', new THREE.Float32BufferAttribute(uv2Array, 2));
};

const computerUV3 = (mesh) => {
  const geometry = mesh.geometry;

  const uv1 = geometry.getAttribute('uv');
  // console.log(uv1, 'uv1');

  geometry.setAttribute('uv2', uv1);

  //开始计算
  const positionArray = geometry.attributes.position.array;
  const normalArray = geometry.attributes.normal.array;
  const originalUVArray = geometry.attributes.uv.array;
  const worldPositionArray = []; //position的世界坐标
  const worldNormalArray = [];
  const originalUVArrays = [];
  mesh.updateMatrixWorld();

  const dirNormal = new THREE.Vector3(0, 0, 1);
  const matrix3 = new THREE.Matrix3();
  matrix3.getNormalMatrix(mesh.matrixWorld.clone());

  for (let i = 0; i < positionArray.length; i += 3) {
    const x = positionArray[i];
    const y = positionArray[i + 1];
    const z = positionArray[i + 2];

    const nx = normalArray[i];
    const ny = normalArray[i + 1];
    const nz = normalArray[i + 2];
    const normal = new THREE.Vector3(nx, ny, nz);

    normal.applyMatrix3(matrix3.clone());
    normal.normalize();

    const localPoint = new THREE.Vector3(x, y, z);
    mesh.localToWorld(localPoint);
    worldPositionArray.push(localPoint);
    worldNormalArray.push(normal);

    const uv = new THREE.Vector2(originalUVArray[i], originalUVArray[i + 1]);
    originalUVArrays.push(uv);

    // //计算向量夹角
    // const angle = dirNormal.clone().dot(normal);

    // //怎么判断同向
    // if (angle > 0) {
    //   console.log('同向');
    // } else {
    //   console.log('反向');
    // }
  }

  const box = new THREE.Box3();
  box.setFromPoints(worldPositionArray);
  const size = box.getSize(new THREE.Vector3());

  const uv3Array = [];
  for (let i = 0; i < worldPositionArray.length; i++) {
    const p = worldPositionArray[i];

    const u = 1 - (box.max.x - p.x) / size.x;
    const v = 1 - (box.max.y - p.y) / size.y;

    const angle = worldNormalArray[i].clone().dot(dirNormal);
    if (angle > 0) {
      console.log('同向');
      uv3Array.push(u, v);
    } else {
      const uv = originalUVArrays[i];
      uv3Array.push(0, 0);
      console.log('反向');
    }
  }

  geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uv3Array, 2));
};

//加载模型
const loader = new GLTFLoader();
loader.load('/public/models/stone2.glb', (model) => {
  model.scene.traverse((child) => {
    if (child.material) {
      computerUV3(child);
      child.material = new CustomShaderMaterial({
        baseMaterial: child.material,
        vertexShader: vert,
        fragmentShader: frag,
        uniforms: {
          texture2: {
            value: new THREE.TextureLoader().load('/public/texture/test1.png'),
          },
        },
      });
    }
  });

  TS.scene.add(model.scene);
});
loader.load('/public/models/stone1.glb', (model) => {
  model.scene.traverse((child) => {
    if (child.material) {
      computerUV3(child);
      child.material = new CustomShaderMaterial({
        baseMaterial: child.material,
        vertexShader: vert,
        fragmentShader: frag,
        uniforms: {
          texture2: {
            value: new THREE.TextureLoader().load('/public/texture/test1.png'),
          },
        },
      });
    }
  });

  model.scene.position.set(0, 10, 0);
  TS.scene.add(model.scene);
});

const panel = new Pane();

panel.addButton({ label: '导出参数', title: '参数名称' }).on('click', () => {});
